<template>
	<view class="cc-upload-media" :style="{'--primary': $theme.primary}">
		<slot>
			<view class="cc-upload-media__add-group">
				<view 
					v-if="renderImage"
					:class="['cc-upload-media__add-group__add', 'iconfont', 'icon-camera', disabled ? 'cc-upload-media__add-group__gray' : '']"
					:style="{background: buttonBackground('Image')}"
					@click="addImage"
				></view>
				<view 
					v-if="renderVideo"
					:class="['cc-upload-media__add-group__add', 'iconfont', 'icon-video', disabled ? 'cc-upload-media__add-group__gray' : '']"
					:style="{background: buttonBackground('Video')}"
					@click="addVideo"
				></view>
				<view 
					v-if="renderAudio"
					:class="['cc-upload-media__add-group__add', 'iconfont', 'icon-audio', disabled ? 'cc-upload-media__add-group__gray' : '']"
					:style="{background: buttonBackground('Audio')}"
					@click="addAudio"
				></view>
			</view>
		</slot>
		<!-- 录音预览 -->
		<view class="cc-upload-media__player" v-if="renderAudio && audio.length > 0">
			<view class="cc-upload-media__player__content" @click="playThisAudio(audio[0].previewSrc)">
				<w-audio-gif :paused="!audioPlaying"></w-audio-gif>
				<text>{{audio[0].duration + '"'}}</text>
			</view>
			<text
				v-if="!disabled"
				class="cc-upload-media__player__close iconfont icon-close"
				@click="deleteMedia('audio', 0)"
			></text>
		</view>
		<w-popup
			v-if="renderAudio"
			v-model="audioPopupShow"
			mode="bottom"
			safe-area-inset-bottom
			:mask-close-able="!audioRecording"
		>
			<view class="cc-upload-media__audio-popup">
				<view 
					class="cc-upload-media__audio-popup__button" 
					@click="startRecordAudio"
				>
					<w-audio-gif scale="0.8" v-show="audioRecording"></w-audio-gif>
					<view v-show="!audioRecording" class="iconfont icon-audio"></view>
				</view>
				<view class="cc-upload-media__audio-popup__tip">
					<text>单击{{audioRecording ? '完成' : '录制'}}</text>
					<text>{{audioRecordCount + '"'}}</text>
					<text>/{{audioMaxDuration + '"'}}</text>
				</view>
			</view>
		</w-popup>
		<view class="cc-upload-media__preview">
			<!-- 图片预览 -->
			<block v-if="renderImage">
				<view
					class="cc-upload-media__preview__item"
					v-for="(item, index) in image"
					:key="item.previewSrc"
				>
					<image
						class="cc-upload-media__preview__item__image"
						mode="aspectFill" 
						:src="item.previewSrc" 
						@click="previewImage(image, index)"
					></image>
					<text
						v-if="!disabled"
						class="cc-upload-media__preview__item__close iconfont icon-close"
						@click="deleteMedia('image', index)"
					></text>
				</view>
			</block>
			<!-- 视频预览 -->
			<block v-if="renderVideo">
				<view
					class="cc-upload-media__preview__item"
					v-for="(item, index) in video"
					:key="item.previewSrc"
					@click="previewVideo(item.previewSrc)"
				>
					<image
						v-if="item.previewCover"
						class="cc-upload-media__preview__item__image"
						mode="aspectFill" 
						:src="item.previewCover"
					></image>
					<view v-else class="cc-upload-media__preview__item__image" style="background-color: #444444;"></view>
					<text
						class="cc-upload-media__preview__item__play iconfont icon-play"
					></text>
					<text
						v-if="!disabled"
						class="cc-upload-media__preview__item__close iconfont icon-close"
						@click.stop="deleteMedia('video', index)"
					></text>
				</view>
			</block>
		</view>
		<!-- #ifndef H5 -->
		<video
			v-if="renderVideo && videoShow"
			:id="currentVideoId" 
			:src="currentVideoSrc"
			class="cc-upload-media__video"
			:show-center-play-btn="showCenterPlayBtn"
			@fullscreenchange="fullscreenChange"
		></video>
		<!-- #endif -->
		<!-- #ifdef H5 -->
		<w-popup
			v-if="renderVideo"
			v-model="videoShow"
			mode="center"
			closeable
			:mask-close-able="false"
			border-radius="8"
		>
			<view style="width: 80vw; height: 350rpx; padding: 20rpx; background-color: #000000;">
				<video
					:id="currentVideoId" 
					:src="currentVideoSrc"
					:show-fullscreen-btn="false"
					style="width: 100%; height: 100%;"
					:show-center-play-btn="false"
				></video>
			</view>
		</w-popup>
		<!-- #endif -->
	</view>
</template>

<script>
	/**
	 * cc-upload-media
	 * 媒体上传组件
	 * 每个模块接收的属性值props值均在各模块的混合文件中
	 */
	import mixinImage from './mixinImage.js';
	import mixinVideo from './mixinVideo.js';
	import mixinAudio from './mixinAudio.js';
	import Emitter from '../../libs/util/emitter.js';
	export default {
		name: 'w-upload-media',
		mixins: [mixinImage, mixinVideo, mixinAudio, Emitter],
		props: {
			/**
			 * value结构如下
			 * image: [{src: String}]
			 * video: [{src: String, cover: String}]
			 * audio: [{src: String, duration: Number}]
			 * 注：audio只支持一个文件，为保证数据格式统一，所以写成相同的数组结构
			 */
			value: {
				type: Object,
				default: () => ({
					image: [],
					video: [],
					audio: []
				})
			},
			// 所需功能，传入image则只有图片上传（按需加载，避免代码冗余）
			layout: {
				type: String,
				default: 'image, video, audio'
			},
			disabled: {
				type: Boolean,
				default: false
			},
			// 其中$type将被替换成image/video/audio
			url: {
				type: String,
				default: '$type'
			},
			checkToken: {
				type: Boolean,
				default: false
			}
		},
		computed: {
			renderImage() {
				return /image/.test(this.layout);
			},
			renderVideo() {
				return /video/.test(this.layout);
			},
			renderAudio() {
				return /audio/.test(this.layout);
			},
			buttonBackground() {
				return (val) => {
					return this.$theme['uploadMedia' + val];
				}
			}
		},
		watch: {
			value: {
				handler(newValue) {
					// 如果默认值是null或{} 则将父组件的value值同步成标准格式
					if (newValue == null || Object.keys(newValue).length == 0) {
						this.$emit('input', {
							image: [],
							video: [],
							audio: []
						});
					} else {
						// 如果默认值有数据，则赋值
						if (newValue?.image) {
							this.image = [...newValue.image];
						}
						if (newValue?.video) {
							this.video = [...newValue.video];
						}
						if (newValue?.audio) {
							this.audio = [...newValue.audio];
						}
					}
				},
				deep: true,
				immediate: true
			}
		},
		methods: {
			// 询问是否清空 图片image or 视频video
			isFull(mode) {
				return new Promise(resolve => {
					uni.showModal({
						content: `已经超出可传数量：${this[mode + 'Limit']}，是否清空？`,
						success: e => {
							if (e.confirm) {
								this[mode] = [];
								resolve(true);
							} else {
								resolve(false);
							}
						},
						fail: () => {
							resolve(false);
						}
					});
				});
			},
			// 删除 图片image or 视频video or 录音audio
			deleteMedia(mode, index) {
				this[mode].splice(index, 1);
				this.change();
			},
			// 资源发生改变时
			change() {
				let value = {
					image: [...this.image],
					video: [...this.video],
					audio: [...this.audio]
				};
				this.$emit('input', value);
				this.$emit('change', value);
				this.$nextTick(() => {
					this.dispatch('w-form-item', 'on-form-change', value);
				});
			}
		}
	}
</script>

<style lang="scss" scoped>
	@import '../../libs/css/variable.scss';
	@font-face {font-family: "iconfont";
		src: url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAATUAAsAAAAACYgAAASIAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDSAqFdIUVATYCJAMYCw4ABCAFhG0HXRtQCFGUDk6Y7CMxdh6FQahUrixU4XsET2uv83b3LgguUYCSFbKKIlBxpCJMVCtdq0QVsK7+P72bvkvQq1tqahu2OQ0JS4f4xGDq9iUOE9Pv/nGvasbSgM1n3+Iy96BcKBwOUID27MBFFVsg5YJoH+KdqB3mfQKthqVBGw1tEhApYFkgHjm1EkQJrVJRGJqFumBvgfgIleY0i7gB4IP38/EPckIEkioDrD15qFdB1U+vryGkvc8OZw4KeMOZIRwiYwYoxFuh9RUZRGeQWrW/wLMHtGuWlJ9eHwI+RH3QfA3p6yMhBGdoxyhFGu4fryJqYKTtNP4gVvHTy0Io/AxASPyMQsj81CAE/0K0KlpZi3O68BUgdgCUM8NL8+G/YB7s7u4vdvdMR+7hyDfUnTdyRRBajvFsf1gWMODhQ6nLJXc6ZQ8e9BAxU5DPMv4y0un0xzJ3CV7+YMycXfads3c79uBa5AcPJGaXi24sRTxJArXq1btn74SlAVBmRSuCUmKovQ3w1p32XW4ec/Y4didg1GbDuAfvJA/fS10f5c4PQ5YN6w6USZb2PilILlvu2DMnQCpfMd7H+Euk41QnnRm7EX/D/cI5ycyph2krx0nQ6vMJnlvPBvNWnYv32nEhDEm37QkjV+/WLPXHywMnfY7bsgCjDMndr9mF4SJxExaFCxfuH4zqBg2qs0WI70N10RjrnLv8mq7wfg39GJbPY9JPZwxuSB/8OXNGtnet/+rEVYm7End/VyCrlVAgy2HbIoI2IwWKxkDffZqY6iDoK8Q1dTKNkMVyYy892eEMRCsTR/sK86IJ8/q1owgrsWGtZUhzgp8A3uPH+FQR8w9fmRUgH5e1KnGFf7t/ZsJYapx8rs/x6+SCcqCy4R4vOJh3j2WxbFsYlSH787jTcc+WgviZj3lOfh53RrQEeTSbPQMWe1LvFBZ0ei0WRxnwqo2UPfGgIs9O1UZYSv0mNa/EuRu7NubiKk+0Mr1DeIfQEHcUxYLhhuGCLCeUWaUu7SU2GA/OKNJ/GitII8kBNOaRfwK2t/hZPkZGApA/E69+st+x/TQ/aphX2f9mNx7Al7VPEO1pzONBN+6fItOY90vxGnYVXQC6uqidrTqB2upr+ERCq1b8SM5eL4aSDzTOJzQbiCBpMgRZsxF0wc9Apc0s1JotQ6tpjYfb9DEhRREDU6ZRELodgKTTJ8i63UQX/HOoDPoOte4godVp+J3ZZiw4XGtilBZGRfWMoThar2OJwYL9wn6M2qpRmuICjyJjTGYuQGVnZKUTjYyOMQ2xwWxT51gsLMWa9FqqgXoYo9HoKYNJ38vQlowRFouhJDOTLXqnDFqvBWydCUPJgqFC6TEGhUPT02GdwRY48/39MNSsNJRMFR01ZhmGiRk3OiVbhqwG6EaprlHHpUw2s1HLYWHBsotYJnpalAbazNBgVI9iKJ7Vi0GzyDCiQ9igRCbTi20qzZherr3LQ9AKLquDQCTiIT4SICG0XHPptFK771v4GusYTidQW5W6Hk58JlcMM2iUY7CNUzH6dJbTaAAA') format('woff2')
	}
	
	.iconfont {
		font-family: "iconfont" !important;
		font-size: 32rpx;
		font-style: normal;
		-webkit-font-smoothing: antialiased;
		-moz-osx-font-smoothing: grayscale;
	}
	
	.icon-camera:before {
		content: "\e66c";
	}
	
	.icon-audio:before {
		content: "\e615";
	}
	
	.icon-close:before {
		content: "\e61f";
	}
	
	.icon-play:before {
		content: "\e60f";
	}
	
	.icon-video:before {
		content: "\eb19";
	}

	.cc-upload-media {
		width: 100%;
		position: relative;
		&__add-group {
			position: absolute;
			right: 0;
			top: -$form-item-height;
			display: flex;
			align-items: center;
			&__add {
				height: 60rpx;
				width: 60rpx;
				border-radius: 50%;
				display: flex;
				align-items: center;
				justify-content: center;
				margin-left: 30rpx;
				color: #FFFFFF;
				font-size: 36rpx;
			}
			&__gray {
				opacity: 0.5;
			}
		}
		&__player {
			display: flex;
			align-items: center;
			&__content {
				height: 55rpx;
				width: 220rpx;
				background: var(--primary);
				border-radius: 8rpx;
				margin-top: 20rpx;
				margin-right: 20rpx;
				display: flex;
				justify-content: space-between;
				align-items: center;
				box-sizing: border-box;
				padding: 0 20rpx;
				text {
					color: #fff;
					font-size: 28rpx;
				}
			}
			&__close {
				right: -16rpx;
				top: -16rpx;
				line-height: 1;
				background-color: #FFFFFF;
				border-radius: 50%;
				color: #bbb;
			}
		}
		&__preview {
			flex-wrap: wrap;
			display: flex;
			padding-bottom: 10rpx;
			&__item {
				height: 140rpx;
				width: 140rpx;
				margin-top: 30rpx;
				margin-right: 30rpx;
				position: relative;
				&:nth-child(n + 5) {
					margin-top: 30rpx;
				}
				&:nth-child(4n) {
					margin-right: 0;
				}
				&__image {
					height: 100%;
					width: 100%;
				}
				&__play {
					height: 60rpx;
					width: 60rpx;
					position: absolute;
					left: 50%;
					top: 50%;
					transform: translate(-50%, -50%);
					background: rgba(0, 0, 0, 0.5);
					color: #FFF;
					font-size: 30rpx;
					border-radius: 50%;
					text-align: center;
				}
				&__close {
					position: absolute;
					right: -16rpx;
					top: -16rpx;
					line-height: 1;
					background-color: #FFFFFF;
					border-radius: 50%;
					color: #bbb;
				}
			}
		}
		&__video {
			position: absolute;
			right: -110%;
		}
		.cc-upload-media__audio-popup {
			height: 200rpx;
			display: flex;
			align-items: center;
			padding-left: 100rpx;
			&__button {
				border: 4px solid rgba(255, 255, 255, 0.9);
				border-radius: 50%;
				height: 120rpx;
				width: 120rpx;
				background: var(--primary);
				display: flex;
				align-items: center;
				justify-content: center;
				margin-right: 50rpx;
				box-sizing: border-box;
				.iconfont {
					color: #fff;
					font-size: 52rpx;
				}
				&:active {
					opacity: 0.8;
				}
			}
			&__tip {
				font-size: 30rpx;
				display: flex;
				text:nth-child(2) {
					margin-left: 20rpx;
					color: var(--primary);
					font-size: 34rpx;
				}
			}
		}
	}
</style>
